﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.Controls;
using YArchitech.Revit;
using YJKArchUtils.Utils;

namespace YJKColumnModify.WallAlignToColumn
{
	public class AlignOperator
	{
		public AlignOperator(Face face, Autodesk.Revit.DB.Document doc)
		{
			this.m_selFace = face;
			this.m_doc = doc;
			this.m_columnLine = this.GetFaceVerticalBaesZCurve(face);
		}

		public void MoveElement(Reference reference)
		{
			bool flag = false;
			Element element = this.m_doc.GetElement(reference);
			Wall wall = element as Wall;
			Face face = element.GetGeometryObjectFromReference(reference) as Face;
			Curve faceVerticalBaesZCurve = this.GetFaceVerticalBaesZCurve(face);
			Line lineUV = AlignOperator.GetLineUV((wall.Location as LocationCurve).Curve as Line);
			XYZ xyz = (lineUV.GetEndPoint(0) + lineUV.GetEndPoint(1)) / 2.0;
			Curve curve = faceVerticalBaesZCurve.Clone();
			curve.MakeUnbound();
			XYZ xyz2 = curve.Project(xyz).XYZPoint - xyz;
			if (xyz2.Normalize().IsAlmostEqualTo(wall.Orientation.Normalize()))
			{
				flag = true;
			}
			if (null == this.m_columnLine)
			{
				return;
			}
			XYZ xyz3 = null;
			try
			{
				xyz3 = ((PlanarFace)this.m_selFace).FaceNormal;
			}
			catch
			{
				return;
			}
			if (Geometry.GreaterThan(xyz2.Normalize().AngleTo(xyz3), Math.PI*.5))
			{
				xyz3 = -xyz3;
			}
			if (!Geometry.IsParallel(lineUV.Direction, this.m_columnLine.Direction, 1E-09))
			{
				XYZ xyz4 = xyz2.Normalize().CrossProduct(xyz3).Normalize();
				double dDegree = xyz2.Normalize().AngleOnPlaneTo(xyz3, xyz4);
				this.RotateElem(wall, xyz, xyz4, dDegree);
			}
			this.m_doc.Regenerate();
			Line lineUV2 = AlignOperator.GetLineUV((wall.Location as LocationCurve).Curve as Line);
			XYZ xyz5 = (lineUV2.GetEndPoint(0) + lineUV2.GetEndPoint(1)) / 2.0;
			XYZ xyz6;
			if (flag)
			{
				xyz6 = xyz5 + wall.Orientation * (wall.Width / 2.0);
			}
			else
			{
				xyz6 = xyz5 - wall.Orientation * (wall.Width / 2.0);
			}
			Curve curve2 = this.m_columnLine.Clone();
			curve2.MakeUnbound();
			XYZ xyz7 = curve2.Project(xyz5).XYZPoint - xyz6;
			XYZ xyz8 = xyz7.Normalize() * xyz7.GetLength();
			ElementTransformUtils.MoveElement(this.m_doc, wall.Id, xyz8);
		}

		public Line GetFaceVerticalBaesZCurve(Face face)
		{
			Line line = null;
			List<CurveLoop> list = face.GetEdgesAsCurveLoops().ToList<CurveLoop>();
			if (list.Count > 0)
			{
				foreach (Curve curve in list[0])
				{
					if (!(curve is Arc) && Geometry.IsVertical((curve as Line).Direction, XYZ.BasisZ, 1E-09))
					{
						line = (curve as Line);
						break;
					}
				}
			}
			Line result = null;
			if (null != line)
			{
				result = AlignOperator.GetLineUV(line);
			}
			return result;
		}

		private static Line GetLineUV(Line line)
		{
			XYZ endPoint = line.GetEndPoint(0);
			XYZ endPoint2 = line.GetEndPoint(1);
			XYZ xyz = new XYZ(endPoint.X, endPoint.Y, 0.0);
			XYZ xyz2 = new XYZ(endPoint2.X, endPoint2.Y, 0.0);
			return Line.CreateBound(xyz, xyz2);
		}

		private bool RotateElem(Element ele, XYZ basePnt, XYZ vector, double dDegree)
		{
			if (ele == null)
			{
				YJKMessageBox.Show("族实例不能为空！");
				return false;
			}
			Document document = ele.Document;
			Line line = document.CreatYJKLine(basePnt, vector, false);
			ElementTransformUtils.RotateElement(document, ele.Id, line, dDegree);
			return true;
		}

		private Face m_selFace;

		private Document m_doc;

		public Line m_columnLine;
	}
}
